﻿using System;
using System.Data;
using System.IO;
using System.Reflection;
using IBatisNet.DataMapper;
using IBatisNet.DataMapper.Configuration;
using NDapper;
using StructureMap.Configuration.DSL;
using StructureMap.Graph;
using StructureMap.Pipeline;
using WebApp.Repositories;
using WebApp.Services;

namespace WebApp.Bootstrap.StructureMap
{
    /*
     * The below configuration tells StructureMap to inject CategoryService when there is a request for ICategoryService. 
     * And also inject CategoryRepository when there is a request for ICategoryRepository. 
     * The CategoryRepository class has a dependency with DbConnection. 
     * So we configure that create a new instance DbConnection when there is request for DbConnection. 
     * we are telling the StructureMapConfiguration to make hybrid instance scope. 
     * The below are the different type of instance scoping, 
     * 1. PerRequest - The default operation.  A new instance will be created for each request.
     * 2. Singleton - A single instance will be shared across all requests
     * 3. ThreadLocal - A single instance will be created for each requesting thread.  Caches the instances with ThreadLocalStorage.
     * 4. HttpContext - A single instance will be created for each HttpContext.  Caches the instances in the HttpContext.Items collection.
     * 5. Hybrid - Uses HttpContext storage if it exists, otherwise uses ThreadLocal storage
     */

    public class SRegistry : Registry
    {
        public SRegistry()
        {
            For<ICategoryRepository>().Singleton().Use<DBCategoryRepository>();
            For<ICategoryService>().Singleton().Use<CategoryService>();
        }
    }

    public class DBRegistry : Registry
    {
        public DBRegistry()
        {
            For<IDapperContext>().Singleton()
                .Use<DapperContext>();

            For<IDbConnection>().LifecycleIs(new UniquePerRequestLifecycle())
                .Use(ctx => ctx.GetInstance<IDapperContext>().Connection);

            Assembly assembly = Assembly.Load("WebApp");
            Stream stream = assembly.GetManifestResourceStream("WebApp.SqlMap.config");

            For<ISqlMapper>().LifecycleIs(new UniquePerRequestLifecycle())
                .Use(x => new DomSqlMapBuilder().Configure(stream));
        }
    }

    public class SimpleConvention : IRegistrationConvention
    {
        public void Process(Type type, Registry registry)
        {
            throw new NotImplementedException();
        }
    }
}